﻿//#region Copyright (c) 2008 plexBB Team
///*  Copyright (c) 2008 plexBB Team
// *  
// *  This file is free software: you may copy, redistribute and/or modify it  
// *  under the terms of the GNU General Public License as published by the  
// *  Free Software Foundation, either version 2 of the License, or (at your  
// *  option) any later version.  
// *  
// *  This file is distributed in the hope that it will be useful, but  
// *  WITHOUT ANY WARRANTY; without even the implied warranty of  
// *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  
// *  General Public License for more details.  
// *  
// *  You should have received a copy of the GNU General Public License  
// *  along with this program.  If not, see <http://www.gnu.org/licenses/>. 
// */
//#endregion

//using System;
//using System.Collections;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Web.UI;
//using System.Web.UI.HtmlControls;
//using System.Web.UI.WebControls;
//using PlexBB.Data;
//using PlexBB.ModuleModel;
//using PlexBB.Controls.Admin;

//namespace PlexBB.Templates.Acp
//{
//    #region ModuleInfo
//    public class AcpModulesInfo : IModuleInfo
//    {
//        public string LangName { get { return "ACP_MODULE_MANAGEMENT"; } }

//        public ModuleMode[] SupportedModes
//        {
//            get { return new[] { new ModuleMode("acp", "ACP"), new ModuleMode("mcp", "MCP"), new ModuleMode("ucp", "UCP") }; }
//        }

//        public void Install() { }

//        public void Uninstall() { }
//    }
//    #endregion

//    [RequiredLangFiles("Acp/Modules", "Ucp")]
//    public abstract class AcpModules : AdminTemplate
//    {
//        private const string _infoSuffix = "Info";
//        private const string _builtInModulesPrefix = "PlexBB.Templates.";
//        private Module _parentModule;

//        #region Controls
//        // Controls
//        protected Control cListErrorBox;
//        protected ITextControl tListError;
//        protected Repeater rModules;
//        protected Control cModulesList;
//        protected Control cModuleEdit;
//        protected Control cModuleActions;
//        protected Repeater rNavigation;
//        protected IButtonControl bEditModule;
//        protected IButtonControl bDeleteModule;
//        protected IButtonControl bDisableModule;
//        protected IButtonControl bEnableModule;
//        // Edit Mode Controls
//        protected Control cEditErrorBox;
//        protected ITextControl tEditError;
//        protected ITextControl tModuleName;
//        protected ITextControl tModuleLangName;
//        protected ListControl sModuleType;
//        protected ListControl sModuleParentID;
//        protected ListControl sModuleEnabled;
//        protected HtmlControl gModOptions;
//        protected ListControl sModuleDisplayed;
//        protected ListControl sChooseModule;
//        protected ListControl sChooseMode;
//        protected IButtonControl bModuleSubmit;
//        protected IButtonControl bBack;
//        #endregion

//        protected ModuleClass ModuleClass
//        {
//            get
//            {
//                switch (Module.ModuleMode)
//                {
//                    case "acp":
//                        return ModuleClass.Acp;
//                    case "mcp":
//                        return ModuleClass.Mcp;
//                    case "ucp":
//                        return ModuleClass.Ucp;
//                    default:
//                        throw new NotSupportedException();
//                }
//            }
//        }

//        protected long? ParentModuleID
//        {
//            get
//            {
//                return (long?)ViewState["ParentModuleID"];
//            }
//            set
//            {
//                ViewState["ParentModuleID"] = value;
//                _parentModule = null;
//            }
//        }

//        protected Module ParentModule
//        {
//            get
//            {
//                if (_parentModule == null && ParentModuleID.HasValue)
//                {
//                    _parentModule = Data.Modules.Single(m => m.ModuleID == ParentModuleID);
//                }
//                return _parentModule;
//            }
//        }

//        protected bool BackToParent
//        {
//            get { return ViewState["BackToParent"] == null ? false : (bool)ViewState["BackToParent"]; }
//            set { ViewState["BackToParent"] = value; }
//        }

//        protected override void OnConfirmYesClick(ConfirmEventArgs e)
//        {
//            switch (e.ConfirmCommand)
//            {
//                case "Delete":
//                    // delete module
//                    Module module = Data.Modules.Single(m => m.ModuleID == (long)e.ConfirmArgument);
//                    if (module.Modules.Count > 0)
//                    {
//                        cListErrorBox.Visible = true;
//                        tListError.Text = Lang["CANNOT_REMOVE_MODULE"];
//                    }
//                    else
//                    {
//                        Data.Modules.DeleteOnSubmit(module);
//                        Data.SubmitChanges();
//                        //                        HideOneControl
//                        ShowMessage(Lang["MODULE_DELETED"]);
//                        if (module == ParentModule)
//                        {
//                            ParentModuleID = ParentModule.ParentID;
//                            DataBindRepeaters();
//                        }
//                        InvalidateModulesCache();
//                    }
//                    break;
//                default:
//                    throw new NotSupportedException();
//            }
//        }

//        protected override void OnLoad(EventArgs e)
//        {
//            base.OnLoad(e);
//            rModules.ItemCommand += rModules_ItemCommand;
//            rNavigation.ItemCommand += rNavigation_ItemCommand;
//            bEditModule.Click += bEditModule_Click;
//            bDeleteModule.Click += bDeleteModule_Click;
//            bDisableModule.Click += bDisableModule_Click;
//            bEnableModule.Click += bEnableModule_Click;
//            bBack.Click += bBack_Click;
//            sChooseModule.SelectedIndexChanged += sChooseModule_SelectedIndexChanged;
//            bModuleSubmit.Click += bModuleSubmit_Click;
//            // error boxes
//            cListErrorBox.EnableViewState = cListErrorBox.Visible = cEditErrorBox.EnableViewState = cEditErrorBox.Visible = false;

//            if (!IsPostBack)
//            {
//                cModuleEdit.Visible = !cModulesList.Visible;
//                DataBindRepeaters();
//            }
//        }

//        protected override void OnPreRender(EventArgs e)
//        {
//            base.OnPreRender(e);

//            if (ParentModule != null && ParentModule.Modules.Count == 0)
//            {
//                cModuleActions.Visible = true;
//                if (bEnableModule != null)
//                {
//                    ((Control)bEnableModule).Visible = !ParentModule.Enabled;
//                }

//                if (bDisableModule != null)
//                {
//                    ((Control)bDisableModule).Visible = ParentModule.Enabled;
//                }
//            }
//            else
//            {
//                cModuleActions.Visible = false;
//            }
//            rModules.Visible = rModules.Items.Count > 0;

//            if (cModuleEdit.Visible)
//            {
//                gModOptions.Style[HtmlTextWriterStyle.Display] = sModuleType != null && sModuleType.SelectedValue == "category" ? "none" : "";
//            }
//        }

//        protected override void OnBackToPrevClick(EventArgs e)
//        {
//            base.OnBackToPrevClick(e);
//            cModuleEdit.Visible = false;
//            cModulesList.Visible = true;
//            if (BackToParent)
//            {
//                ParentModuleID = ParentModule.ParentID;
//            }
//            DataBindRepeaters();
//        }

//        private void bBack_Click(object sender, EventArgs e)
//        {
//            bool backToParent = bool.Parse(bBack.CommandArgument);
//            if (backToParent)
//            {
//                ParentModuleID = ParentModule.ParentID;
//            }
//            // get back from edit mode
//        }

//        #region Module Actions
//        private void bEditModule_Click(object sender, EventArgs e)
//        {
//            SetEditMode(false);
//        }

//        private void AddCategoriesToListRecursive(long? parentModuleID, ListControl control, int level)
//        {
//            var categories = from m in Data.Modules
//                             where m.ModuleClass == ModuleClass && m.ModuleType == null && object.Equals(m.ParentID, parentModuleID)
//                             orderby m.Position
//                             select new { m.ModuleID, m.LangName };
//            foreach (var cat in categories)
//            {
//                StringBuilder catName = new StringBuilder();
//                const char nonBreakSpace = (char)0xA0;
//                for (int i = 0; i < level * 3; i++)
//                {
//                    catName.Append(nonBreakSpace);
//                }
//                catName.Append(Lang[cat.LangName]);

//                ListItem item = new ListItem(catName.ToString(), cat.ModuleID.ToString());
//                control.Items.Add(item);
//                AddCategoriesToListRecursive(cat.ModuleID, control, level + 1);
//            }
//        }

//        private void bDeleteModule_Click(object sender, EventArgs e)
//        {
//            DeleteModule(ParentModule);
//        }

//        private void bDisableModule_Click(object sender, EventArgs e)
//        {
//            ParentModule.Enabled = false;
//            Data.SubmitChanges();
//            InvalidateModulesCache();
//        }

//        private void bEnableModule_Click(object sender, EventArgs e)
//        {
//            ParentModule.Enabled = true;
//            Data.SubmitChanges();
//            InvalidateModulesCache();
//        }
//        #endregion

//        private void InvalidateModulesCache()
//        {
//            GlobalSetting setting = Data.GlobalSettings.SingleOrDefault(s => s.Name == GlobalSetting.CachedModulesVersion);
//            if (setting == null)
//            {
//                setting = new GlobalSetting()
//                {
//                    Name = GlobalSetting.CachedModulesVersion
//                };
//                Data.GlobalSettings.InsertOnSubmit(setting);
//            }
//            setting.Value = Guid.NewGuid().ToString("N");
//            Data.SubmitChanges();

//            ((Overall)PlexBBContext.ActionControl).InvalidateCachedModules();
//        }

//        private void DataBindRepeaters()
//        {
//            rModules.ItemDataBound += rModules_ItemDataBound;
//            rModules.DataSource = (from m in Data.Modules
//                                   where m.ModuleClass == ModuleClass && object.Equals(m.ParentID, ParentModuleID)
//                                   orderby m.Position
//                                   select m).ToList();
//            rModules.DataBind();

//            List<Module> parentModules = new List<Module>();
//            if (ParentModule != null)
//            {
//                Module parent = ParentModule.ParentModule;
//                while (parent != null)
//                {
//                    parentModules.Insert(0, parent);
//                    parent = parent.ParentModule;
//                }
//                parentModules.Insert(0, null);
//            }
//            rNavigation.ItemDataBound += rNavigation_ItemDataBound;
//            rNavigation.DataSource = parentModules;
//            rNavigation.DataBind();
//        }

//        private void rModules_ItemCommand(object source, RepeaterCommandEventArgs e)
//        {
//            Module module = Data.Modules.Single(m => m.ModuleID == Convert.ToInt64(e.CommandArgument));

//            // using object.Equals to make LINQ correctly translate NULL value
//            // used in Up/Down only
//            IQueryable<Module> siblingModules = from m in Data.Modules
//                                                where object.Equals(m.ParentModule, module.ParentModule) && m.ModuleType == module.ModuleType
//                                                select m;
//            switch (e.CommandName)
//            {
//                case "In":
//                    ParentModuleID = module.ModuleID;
//                    break;
//                case "Disable":
//                    module.Enabled = false;
//                    break;
//                case "Enable":
//                    module.Enabled = true;
//                    break;
//                case "Up":
//                    {
//                        Module exchangeModule = (from m in siblingModules
//                                                 where m.Position < module.Position
//                                                 orderby m.Position descending
//                                                 select m).First();
//                        long exchangeModulePosition = exchangeModule.Position;
//                        exchangeModule.Position = module.Position;
//                        module.Position = exchangeModulePosition;
//                    }
//                    break;
//                case "Down":
//                    {
//                        Module exchangeModule = (from m in siblingModules
//                                                 where m.Position > module.Position
//                                                 orderby m.Position
//                                                 select m).First();
//                        long exchangeModulePosition = exchangeModule.Position;
//                        exchangeModule.Position = module.Position;
//                        module.Position = exchangeModulePosition;
//                    }
//                    break;
//                case "Edit":
//                    ParentModuleID = module.ModuleID;
//                    SetEditMode(true);
//                    break;
//                case "Delete":
//                    DeleteModule(module);
//                    break;
//                default:
//                    throw new NotSupportedException();
//            }
//            Data.SubmitChanges();

//            // rebind dependent
//            DataBindRepeaters();
//            InvalidateModulesCache();
//        }

//        private void DeleteModule(Module module)
//        {
//            // show confirm text
//            ShowConfirm(Lang["DELETE_MODULE"], Lang["DELETE_MODULE_CONFIRM"], "Delete", module.ModuleID);
//        }

//        private void rModules_ItemDataBound(object sender, RepeaterItemEventArgs e)
//        {
//            if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem)
//            {
//                return;
//            }

//            Module module = (Module)e.Item.DataItem;

//            #region iModuleImage
//            Image iModuleImage = e.Item.Find<Image>("iModuleImage");
//            if (!module.Enabled)
//            {
//                iModuleImage.ImageUrl = "../images/icon_folder_lock.gif";
//                iModuleImage.AlternateText = Lang["DEACTIVATED_MODULE"];
//            }
//            else if (module.IsCategory)
//            {
//                iModuleImage.ImageUrl = "../images/icon_subfolder.gif";
//                iModuleImage.AlternateText = Lang["CATEGORY"];
//            }
//            else
//            {
//                iModuleImage.ImageUrl = "../images/icon_folder.gif";
//                iModuleImage.AlternateText = Lang["MODULE"];
//            }
//            #endregion

//            #region bModuleTitle
//            IButtonControl bModuleTitle = e.Item.Find<IButtonControl>("bModuleTitle");
//            bModuleTitle.Text = Lang[module.LangName];
//            bModuleTitle.CommandName = "In";
//            bModuleTitle.CommandArgument = module.ModuleID.ToString();
//            #endregion

//            #region cHiddenModule
//            Control cHiddenModule = e.Item.Find<Control>("cHiddenModule");
//            cHiddenModule.Visible = !module.Display;
//            #endregion

//            #region bDisable
//            IButtonControl bDisable = e.Item.Find<IButtonControl>("bDisable");
//            bDisable.CommandName = "Disable";
//            bDisable.CommandArgument = module.ModuleID.ToString();
//            ((Control)bDisable).Visible = module.Enabled;
//            #endregion

//            #region bEnable
//            IButtonControl bEnable = e.Item.Find<IButtonControl>("bEnable");
//            bEnable.CommandName = "Enable";
//            bEnable.CommandArgument = module.ModuleID.ToString();
//            ((Control)bEnable).Visible = !module.Enabled;
//            #endregion

//            bool firstRow = e.Item.ItemIndex == 0;
//            bool lastRow = e.Item.ItemIndex == ((IList)rModules.DataSource).Count - 1;

//            #region bUp
//            IButtonControl bUp = e.Item.Find<IButtonControl>("bUp");
//            bUp.CommandName = "Up";
//            bUp.CommandArgument = module.ModuleID.ToString();
//            ((Control)bUp).Visible = !firstRow;
//            #endregion

//            #region cUpDisabled
//            Control cUpDisabled = e.Item.Find<Control>("cUpDisabled");
//            cUpDisabled.Visible = firstRow;
//            #endregion

//            #region bDown
//            IButtonControl bDown = e.Item.Find<IButtonControl>("bDown");
//            bDown.CommandName = "Down";
//            bDown.CommandArgument = module.ModuleID.ToString();
//            ((Control)bDown).Visible = !lastRow;
//            #endregion

//            #region cDownDisabled
//            Control cDownDisabled = e.Item.Find<Control>("cDownDisabled");
//            cDownDisabled.Visible = lastRow;
//            #endregion

//            #region bEdit
//            IButtonControl bEdit = e.Item.Find<IButtonControl>("bEdit");
//            bEdit.CommandName = "Edit";
//            bEdit.CommandArgument = module.ModuleID.ToString();
//            #endregion

//            #region bDelete
//            IButtonControl bDelete = e.Item.Find<IButtonControl>("bDelete");
//            bDelete.CommandName = "Delete";
//            bDelete.CommandArgument = module.ModuleID.ToString();
//            #endregion
//        }

//        private void rNavigation_ItemCommand(object source, RepeaterCommandEventArgs e)
//        {
//            switch (e.CommandName)
//            {
//                case "In":
//                    ParentModuleID = object.Equals(e.CommandArgument, "") ? null : (long?)int.Parse((string)e.CommandArgument);
//                    DataBindRepeaters();
//                    break;
//                default:
//                    throw new NotSupportedException();
//            }
//        }

//        private void rNavigation_ItemDataBound(object sender, RepeaterItemEventArgs e)
//        {
//            Module module = (Module)e.Item.DataItem;

//            IButtonControl bNavigate = e.Item.Find<IButtonControl>("bNavigate", false);
//            if (bNavigate != null)
//            {
//                bNavigate.Text = module == null ? ModuleClass.ToString().ToUpper() : Lang[module.LangName];
//                bNavigate.CommandName = "In";
//                bNavigate.CommandArgument = module == null ? null : module.ModuleID.ToString();
//            }

//            Label lCurrentModule = e.Item.Find<Label>("lCurrentModule", false);
//            if (lCurrentModule != null)
//            {
//                lCurrentModule.Text = ParentModule == null ? ModuleClass.ToString().ToUpper() : Lang[ParentModule.LangName];
//            }
//        }

//        private void SetEditMode(bool backToParent)
//        {
//            BackToParent = backToParent;
//            cModuleEdit.Visible = true;
//            cModulesList.Visible = false;
//            tModuleName.Text = Lang[ParentModule.LangName];
//            tModuleLangName.Text = ParentModule.LangName;
//            string selectedValue = ParentModule.IsCategory ? "category" : "module";
//            sModuleType.SelectedIndex = -1;
//            sModuleType.Items.FindByValue(selectedValue).Selected = true;

//            // build full categories hierarchy
//            ListItem noParentItem = new ListItem(Lang["NO_PARENT"], "");
//            sModuleParentID.Items.Add(noParentItem);
//            AddCategoriesToListRecursive(null, sModuleParentID, 0);

//            SetYesNoList(sModuleEnabled, ParentModule.Enabled);
//            SetYesNoList(sModuleDisplayed, ParentModule.Display);

//            Type moduleInfoType = typeof(IModuleInfo);

//            // select all available modules from all loaded assemblies
//            var modules = AppDomain.CurrentDomain.GetAssemblies().Select(assembly =>
//                from type in assembly.GetTypes()
//                where moduleInfoType.IsAssignableFrom(type) && !type.IsInterface && !type.IsAbstract && type.FullName.EndsWith(_infoSuffix)
//                let name = type.FullName.StartsWith(_builtInModulesPrefix) ? type.FullName.Substring(_builtInModulesPrefix.Length) : type.FullName
//                select new
//                {
//                    Text = string.Format("{0} [{1}]",
//                        Lang[((IModuleInfo)Activator.CreateInstance(type)).LangName],
//                        name.Substring(0, name.Length - _infoSuffix.Length)),
//                    Value = type.FullName
//                }).SelectMany(t => t).OrderBy(t => t.Text);

//            sChooseModule.DataTextField = "Text";
//            sChooseModule.DataValueField = "Value";
//            sChooseModule.DataSource = modules;
//            sChooseModule.DataBind();
//            sChooseModule.TrySelectValue(ParentModule.ModuleType + _infoSuffix);

//            SetModuleModes();
//            sChooseMode.TrySelectValue(ParentModule.ModuleMode);
//        }

//        private void sChooseModule_SelectedIndexChanged(object sender, EventArgs e)
//        {
//            SetModuleModes();
//        }

//        private void SetModuleModes()
//        {
//            string moduleInfoType = sChooseModule.SelectedValue;
//            IModuleInfo moduleInfo = (IModuleInfo)Activator.CreateInstance(Type.GetType(moduleInfoType));

//            sChooseMode.DataSource = from mode in moduleInfo.SupportedModes
//                                     let name = Lang[mode.LangName]
//                                     orderby name
//                                     select new { Text = name, Value = mode.ModeName };
//            sChooseMode.DataTextField = "Text";
//            sChooseMode.DataValueField = "Value";

//            sChooseMode.DataBind();
//        }

//        private void bModuleSubmit_Click(object sender, EventArgs e)
//        {
//            if (Page.IsValid)
//            {
//                ParentModule.LangName = tModuleLangName.Text.Trim();
//                ParentModule.Enabled = bool.Parse(sModuleEnabled.SelectedValue);
//                if (sModuleType.SelectedValue == "category")
//                {
//                    ParentModule.ModuleType = null;
//                    ParentModule.ModuleMode = null;
//                    ParentModule.Display = true;
//                }
//                else
//                {
//                    ParentModule.ModuleType = sChooseModule.SelectedValue.Substring(0, sChooseModule.SelectedValue.Length - _infoSuffix.Length);
//                    ParentModule.ModuleMode = sChooseMode.SelectedValue;
//                    ParentModule.Display = bool.Parse(sModuleDisplayed.SelectedValue);
//                }
//                Data.SubmitChanges();

//                ShowMessage(Lang["MODULE_EDITED"]);
//            }
//        }
//    }
//}
